home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / ncurses-5.3 / ncurses / base / lib_set_term.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-27  |  13.3 KB  |  480 lines

  1. /****************************************************************************
  2.  * Copyright (c) 1998-2001,2002 Free Software Foundation, Inc.              *
  3.  *                                                                          *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a  *
  5.  * copy of this software and associated documentation files (the            *
  6.  * "Software"), to deal in the Software without restriction, including      *
  7.  * without limitation the rights to use, copy, modify, merge, publish,      *
  8.  * distribute, distribute with modifications, sublicense, and/or sell       *
  9.  * copies of the Software, and to permit persons to whom the Software is    *
  10.  * furnished to do so, subject to the following conditions:                 *
  11.  *                                                                          *
  12.  * The above copyright notice and this permission notice shall be included  *
  13.  * in all copies or substantial portions of the Software.                   *
  14.  *                                                                          *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
  16.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
  18.  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
  21.  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
  22.  *                                                                          *
  23.  * Except as contained in this notice, the name(s) of the above copyright   *
  24.  * holders shall not be used in advertising or otherwise to promote the     *
  25.  * sale, use or other dealings in this Software without prior written       *
  26.  * authorization.                                                           *
  27.  ****************************************************************************/
  28.  
  29. /****************************************************************************
  30.  *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
  31.  *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
  32.  ****************************************************************************/
  33.  
  34. /*
  35. **    lib_set_term.c
  36. **
  37. **    The routine set_term().
  38. **
  39. */
  40.  
  41. #include <curses.priv.h>
  42.  
  43. #include <term.h>        /* cur_term */
  44. #include <tic.h>
  45.  
  46. MODULE_ID("$Id: lib_set_term.c,v 1.71 2002/09/14 22:48:00 tom Exp $")
  47.  
  48. NCURSES_EXPORT(SCREEN *)
  49. set_term(SCREEN * screenp)
  50. {
  51.     SCREEN *oldSP;
  52.  
  53.     T((T_CALLED("set_term(%p)"), screenp));
  54.  
  55.     oldSP = SP;
  56.     _nc_set_screen(screenp);
  57.  
  58.     set_curterm(SP->_term);
  59.     curscr = SP->_curscr;
  60.     newscr = SP->_newscr;
  61.     stdscr = SP->_stdscr;
  62.     COLORS = SP->_color_count;
  63.     COLOR_PAIRS = SP->_pair_count;
  64.     memcpy(acs_map, SP->_acs_map, sizeof(SP->_acs_map[0]) * ACS_LEN);
  65.  
  66.     T((T_RETURN("%p"), oldSP));
  67.     return (oldSP);
  68. }
  69.  
  70. static void
  71. _nc_free_keytry(struct tries *kt)
  72. {
  73.     if (kt != 0) {
  74.     _nc_free_keytry(kt->child);
  75.     _nc_free_keytry(kt->sibling);
  76.     free(kt);
  77.     }
  78. }
  79.  
  80. /*
  81.  * Free the storage associated with the given SCREEN sp.
  82.  */
  83. NCURSES_EXPORT(void)
  84. delscreen(SCREEN * sp)
  85. {
  86.     SCREEN **scan = &_nc_screen_chain;
  87.  
  88.     T((T_CALLED("delscreen(%p)"), sp));
  89.  
  90.     while (*scan) {
  91.     if (*scan == sp) {
  92.         *scan = sp->_next_screen;
  93.         break;
  94.     }
  95.     scan = &(*scan)->_next_screen;
  96.     }
  97.  
  98.     (void) _nc_freewin(sp->_curscr);
  99.     (void) _nc_freewin(sp->_newscr);
  100.     (void) _nc_freewin(sp->_stdscr);
  101.  
  102.     if (sp->_slk != 0) {
  103.     FreeIfNeeded(sp->_slk->ent);
  104.     FreeIfNeeded(sp->_slk->buffer);
  105.     free(sp->_slk);
  106.     sp->_slk = 0;
  107.     }
  108.  
  109.     _nc_free_keytry(sp->_keytry);
  110.     sp->_keytry = 0;
  111.  
  112.     _nc_free_keytry(sp->_key_ok);
  113.     sp->_key_ok = 0;
  114.  
  115.     FreeIfNeeded(sp->_color_table);
  116.     FreeIfNeeded(sp->_color_pairs);
  117.  
  118.     FreeIfNeeded(sp->oldhash);
  119.     FreeIfNeeded(sp->newhash);
  120.     FreeIfNeeded(sp->hashtab);
  121.  
  122.     del_curterm(sp->_term);
  123.  
  124.     /*
  125.      * If the associated output stream has been closed, we can discard the
  126.      * set-buffer.  Limit the error check to EBADF, since fflush may fail
  127.      * for other reasons than trying to operate upon a closed stream.
  128.      */
  129.     if (sp->_ofp != 0
  130.     && sp->_setbuf != 0
  131.     && fflush(sp->_ofp) != 0
  132.     && errno == EBADF) {
  133.     free(sp->_setbuf);
  134.     }
  135.  
  136.     free(sp);
  137.  
  138.     /*
  139.      * If this was the current screen, reset everything that the
  140.      * application might try to use (except cur_term, which may have
  141.      * multiple references in different screens).
  142.      */
  143.     if (sp == SP) {
  144.     curscr = 0;
  145.     newscr = 0;
  146.     stdscr = 0;
  147.     COLORS = 0;
  148.     COLOR_PAIRS = 0;
  149.     _nc_set_screen(0);
  150.     }
  151.     returnVoid;
  152. }
  153.  
  154. static ripoff_t rippedoff[5];
  155. static ripoff_t *rsp = rippedoff;
  156. #define N_RIPS SIZEOF(SP->_rippedoff)
  157.  
  158. static bool
  159. no_mouse_event(SCREEN * sp GCC_UNUSED)
  160. {
  161.     return FALSE;
  162. }
  163.  
  164. static bool
  165. no_mouse_inline(SCREEN * sp GCC_UNUSED)
  166. {
  167.     return FALSE;
  168. }
  169.  
  170. static bool
  171. no_mouse_parse(int code GCC_UNUSED)
  172. {
  173.     return TRUE;
  174. }
  175.  
  176. static void
  177. no_mouse_resume(SCREEN * sp GCC_UNUSED)
  178. {
  179. }
  180.  
  181. static void
  182. no_mouse_wrap(SCREEN * sp GCC_UNUSED)
  183. {
  184. }
  185.  
  186. #if NCURSES_EXT_FUNCS && USE_COLORFGBG
  187. static char *
  188. extract_fgbg(char *src, int *result)
  189. {
  190.     char *dst = 0;
  191.     long value = strtol(src, &dst, 0);
  192.  
  193.     if (dst == 0) {
  194.     dst = src;
  195.     } else if (value >= 0) {
  196.     *result = value;
  197.     }
  198.     while (*dst != 0 && *dst != ';')
  199.     dst++;
  200.     if (*dst == ';')
  201.     dst++;
  202.     return dst;
  203. }
  204. #endif
  205.  
  206. NCURSES_EXPORT(int)
  207. _nc_setupscreen(short slines, short const scolumns, FILE * output)
  208. /* OS-independent screen initializations */
  209. {
  210.     int bottom_stolen = 0;
  211.     size_t i;
  212.  
  213.     T((T_CALLED("_nc_setupscreen(%d, %d, %p)"), slines, scolumns, output));
  214.     assert(SP == 0);        /* has been reset in newterm() ! */
  215.     if (!_nc_alloc_screen())
  216.     returnCode(ERR);
  217.  
  218.     SP->_next_screen = _nc_screen_chain;
  219.     _nc_screen_chain = SP;
  220.  
  221.     _nc_set_buffer(output, TRUE);
  222.     SP->_term = cur_term;
  223.     SP->_lines = slines;
  224.     SP->_lines_avail = slines;
  225.     SP->_columns = scolumns;
  226.     SP->_cursrow = -1;
  227.     SP->_curscol = -1;
  228.     SP->_nl = TRUE;
  229.     SP->_raw = FALSE;
  230.     SP->_cbreak = 0;
  231.     SP->_echo = TRUE;
  232.     SP->_fifohead = -1;
  233.     SP->_endwin = TRUE;
  234.     SP->_ofp = output;
  235.     SP->_cursor = -1;        /* cannot know real cursor shape */
  236.  
  237. #if NCURSES_NO_PADDING
  238.     SP->_no_padding = getenv("NCURSES_NO_PADDING") != 0;
  239.     TR(TRACE_CHARPUT | TRACE_MOVE, ("padding will%s be used",
  240.                     SP->_no_padding ? " not" : ""));
  241. #endif
  242.  
  243. #if NCURSES_EXT_FUNCS
  244.     SP->_default_color = FALSE;
  245.     SP->_has_sgr_39_49 = FALSE;
  246.  
  247.     /*
  248.      * Set our assumption of the terminal's default foreground and background
  249.      * colors.  The curs_color man-page states that we can assume that the
  250.      * background is black.  The origin of this assumption appears to be
  251.      * terminals that displayed colored text, but no colored backgrounds, e.g.,
  252.      * the first colored terminals around 1980.  More recent ones with better
  253.      * technology can display not only colored backgrounds, but all
  254.      * combinations.  So a terminal might be something other than "white" on
  255.      * black (green/black looks monochrome too), but black on white or even
  256.      * on ivory.
  257.      *
  258.      * White-on-black is the simplest thing to use for monochrome.  Almost
  259.      * all applications that use color paint both text and background, so
  260.      * the distinction is moot.  But a few do not - which is why we leave this
  261.      * configurable (a better solution is to use assume_default_colors() for
  262.      * the rare applications that do require that sort of appearance, since
  263.      * is appears that more users expect to be able to make a white-on-black
  264.      * or black-on-white display under control of the application than not).
  265.      */
  266. #ifdef USE_ASSUMED_COLOR
  267.     SP->_default_fg = COLOR_WHITE;
  268.     SP->_default_bg = COLOR_BLACK;
  269. #else
  270.     SP->_default_fg = C_MASK;
  271.     SP->_default_bg = C_MASK;
  272. #endif
  273.  
  274.     /*
  275.      * Allow those assumed/default color assumptions to be overridden at
  276.      * runtime:
  277.      */
  278.     if (getenv("NCURSES_ASSUMED_COLORS") != 0) {
  279.     char *p = getenv("NCURSES_ASSUMED_COLORS");
  280.     int fg, bg;
  281.     char sep1, sep2;
  282.     int count = sscanf(p, "%d%c%d%c", &fg, &sep1, &bg, &sep2);
  283.     if (count >= 1) {
  284.         SP->_default_fg = (fg >= 0 && fg < max_colors) ? fg : C_MASK;
  285.         if (count >= 3) {
  286.         SP->_default_bg = (bg >= 0 && bg < max_colors) ? bg : C_MASK;
  287.         }
  288.         TR(TRACE_CHARPUT | TRACE_MOVE,
  289.            ("from environment assumed fg=%d, bg=%d",
  290.         SP->_default_fg,
  291.         SP->_default_bg));
  292.     }
  293.     }
  294. #if USE_COLORFGBG
  295.     /*
  296.      * If rxvt's $COLORFGBG variable is set, use it to specify the assumed
  297.      * default colors.  Note that rxvt (mis)uses bold colors, equating a bold
  298.      * color to that value plus 8.  We'll only use the non-bold color for now -
  299.      * decide later if it is worth having default attributes as well.
  300.      */
  301.     if (getenv("COLORFGBG") != 0) {
  302.     char *p = getenv("COLORFGBG");
  303.     TR(TRACE_CHARPUT | TRACE_MOVE, ("decoding COLORFGBG %s", p));
  304.     p = extract_fgbg(p, &(SP->_default_fg));
  305.     p = extract_fgbg(p, &(SP->_default_bg));
  306.     if (*p)            /* assume rxvt was compiled with xpm support */
  307.         p = extract_fgbg(p, &(SP->_default_bg));
  308.     TR(TRACE_CHARPUT | TRACE_MOVE, ("decoded fg=%d, bg=%d",
  309.                     SP->_default_fg, SP->_default_bg));
  310.     if (SP->_default_fg >= max_colors) {
  311.         if (set_a_foreground != ABSENT_STRING
  312.         && !strcmp(set_a_foreground, "\033[3%p1%dm")) {
  313.         set_a_foreground = "\033[3%?%p1%{8}%>%t9%e%p1%d%;m";
  314.         } else {
  315.         SP->_default_fg %= max_colors;
  316.         }
  317.     }
  318.     if (SP->_default_bg >= max_colors) {
  319.         if (set_a_background != ABSENT_STRING
  320.         && !strcmp(set_a_background, "\033[4%p1%dm")) {
  321.         set_a_background = "\033[4%?%p1%{8}%>%t9%e%p1%d%;m";
  322.         } else {
  323.         SP->_default_bg %= max_colors;
  324.         }
  325.     }
  326.     }
  327. #endif
  328. #endif /* NCURSES_EXT_FUNCS */
  329.  
  330.     SP->_maxclick = DEFAULT_MAXCLICK;
  331.     SP->_mouse_event = no_mouse_event;
  332.     SP->_mouse_inline = no_mouse_inline;
  333.     SP->_mouse_parse = no_mouse_parse;
  334.     SP->_mouse_resume = no_mouse_resume;
  335.     SP->_mouse_wrap = no_mouse_wrap;
  336.     SP->_mouse_fd = -1;
  337.  
  338.     /* initialize the panel hooks */
  339.     SP->_panelHook.top_panel = (struct panel *) 0;
  340.     SP->_panelHook.bottom_panel = (struct panel *) 0;
  341.     SP->_panelHook.stdscr_pseudo_panel = (struct panel *) 0;
  342.  
  343.     /*
  344.      * If we've no magic cookie support, we suppress attributes that xmc
  345.      * would affect, i.e., the attributes that affect the rendition of a
  346.      * space.  Note that this impacts the alternate character set mapping
  347.      * as well.
  348.      */
  349.     if (magic_cookie_glitch > 0) {
  350.  
  351.     SP->_xmc_triggers = termattrs() & (
  352.                           A_ALTCHARSET |
  353.                           A_BLINK |
  354.                           A_BOLD |
  355.                           A_REVERSE |
  356.                           A_STANDOUT |
  357.                           A_UNDERLINE
  358.         );
  359.     SP->_xmc_suppress = SP->_xmc_triggers & (chtype) ~(A_BOLD);
  360.  
  361.     T(("magic cookie attributes %s", _traceattr(SP->_xmc_suppress)));
  362. #if USE_XMC_SUPPORT
  363.     /*
  364.      * To keep this simple, suppress all of the optimization hooks
  365.      * except for clear_screen and the cursor addressing.
  366.      */
  367.     clr_eol = 0;
  368.     clr_eos = 0;
  369.     set_attributes = 0;
  370. #else
  371.     magic_cookie_glitch = ABSENT_NUMERIC;
  372.     acs_chars = 0;
  373. #endif
  374.     }
  375.  
  376.     /* initialize normal acs before wide, since we use mapping in the latter */
  377.     _nc_init_acs();
  378. #if USE_WIDEC_SUPPORT
  379.     _nc_init_wacs();
  380. #endif
  381.     memcpy(SP->_acs_map, acs_map, sizeof(chtype) * ACS_LEN);
  382.  
  383.     _nc_idcok = TRUE;
  384.     _nc_idlok = FALSE;
  385.  
  386.     _nc_windows = 0;        /* no windows yet */
  387.  
  388.     SP->oldhash = 0;
  389.     SP->newhash = 0;
  390.  
  391.     T(("creating newscr"));
  392.     if ((newscr = newwin(slines, scolumns, 0, 0)) == 0)
  393.     returnCode(ERR);
  394.  
  395.     T(("creating curscr"));
  396.     if ((curscr = newwin(slines, scolumns, 0, 0)) == 0)
  397.     returnCode(ERR);
  398.  
  399.     SP->_newscr = newscr;
  400.     SP->_curscr = curscr;
  401. #if USE_SIZECHANGE
  402.     SP->_resize = resizeterm;
  403. #endif
  404.  
  405.     newscr->_clear = TRUE;
  406.     curscr->_clear = FALSE;
  407.  
  408.     def_shell_mode();
  409.     def_prog_mode();
  410.  
  411.     for (i = 0, rsp = rippedoff; rsp->line && (i < N_RIPS); rsp++, i++) {
  412.     T(("ripping off line %d at %s", i, rsp->line < 0 ? "bottom" : "top"));
  413.     SP->_rippedoff[i] = rippedoff[i];
  414.     if (rsp->hook) {
  415.         int count = (rsp->line < 0) ? -rsp->line : rsp->line;
  416.  
  417.         SP->_rippedoff[i].w = newwin(count,
  418.                      scolumns,
  419.                      ((rsp->line < 0)
  420.                       ? SP->_lines_avail - count
  421.                       : 0),
  422.                      0);
  423.         if (SP->_rippedoff[i].w != 0)
  424.         SP->_rippedoff[i].hook(SP->_rippedoff[i].w, scolumns);
  425.         else
  426.         returnCode(ERR);
  427.         if (rsp->line < 0)
  428.         bottom_stolen += count;
  429.         else
  430.         SP->_topstolen += count;
  431.         SP->_lines_avail -= count;
  432.     }
  433.     rsp->line = 0;
  434.     }
  435.     SP->_rip_count = i;
  436.     /* reset the stack */
  437.     rsp = rippedoff;
  438.  
  439.     T(("creating stdscr"));
  440.     assert((SP->_lines_avail + SP->_topstolen + bottom_stolen) == slines);
  441.     if ((stdscr = newwin(LINES = SP->_lines_avail, scolumns, 0, 0)) == 0)
  442.     returnCode(ERR);
  443.     SP->_stdscr = stdscr;
  444.  
  445.     returnCode(OK);
  446. }
  447.  
  448. /* The internal implementation interprets line as the number of
  449.    lines to rip off from the top or bottom.
  450.    */
  451. NCURSES_EXPORT(int)
  452. _nc_ripoffline(int line, int (*init) (WINDOW *, int))
  453. {
  454.     T((T_CALLED("_nc_ripoffline(%d, %p)"), line, init));
  455.  
  456.     if (line != 0) {
  457.  
  458.     if (rsp >= rippedoff + N_RIPS)
  459.         returnCode(ERR);
  460.  
  461.     rsp->line = line;
  462.     rsp->hook = init;
  463.     rsp->w = 0;
  464.     rsp++;
  465.     }
  466.  
  467.     returnCode(OK);
  468. }
  469.  
  470. NCURSES_EXPORT(int)
  471. ripoffline(int line, int (*init) (WINDOW *, int))
  472. {
  473.     T((T_CALLED("ripoffline(%d,%p)"), line, init));
  474.  
  475.     if (line == 0)
  476.     returnCode(OK);
  477.  
  478.     returnCode(_nc_ripoffline((line < 0) ? -1 : 1, init));
  479. }
  480.